const axios = require("axios");

class FeishuService {
  constructor() {
    this.baseURL = "https://open.feishu.cn/open-apis";
    this.accessToken = null;
    this.appKey = null;
    this.appSecret = null;
  }

  async authenticate(appKey, appSecret) {
    this.appKey = appKey;
    this.appSecret = appSecret;

    console.log(`[调试] 开始认证流程`);
    console.log(
      `[调试] App Key: ${appKey ? appKey.substring(0, 8) + "..." : "空"}`
    );
    console.log(`[调试] App Secret: ${appSecret ? "已提供" : "未提供"}`);

    try {
      const authUrl = `${this.baseURL}/auth/v3/tenant_access_token/internal`;
      console.log(`[调试] 认证URL: ${authUrl}`);

      const requestData = {
        app_id: appKey,
        app_secret: appSecret,
      };

      console.log(`[调试] 发送认证请求...`);
      const response = await axios.post(authUrl, requestData, {
        headers: {
          "Content-Type": "application/json; charset=utf-8",
        },
      });

      console.log(`[调试] 认证响应状态: ${response.status}`);
      console.log(`[调试] 认证响应代码: ${response.data.code}`);
      console.log(`[调试] 认证响应消息: ${response.data.msg || "无"}`);

      if (response.data.code !== 0) {
        throw new Error(`认证失败: ${response.data.msg || "未知错误"}`);
      }

      this.accessToken = response.data.tenant_access_token;
      console.log(
        `[调试] 获取到access token: ${
          this.accessToken ? this.accessToken.substring(0, 20) + "..." : "空"
        }`
      );

      // 验证token是否有效
      if (!this.accessToken) {
        throw new Error("认证成功但未获取到access token");
      }

      console.log(`[调试] 认证完成，token已保存`);
      return this.accessToken;
    } catch (error) {
      console.log(`[调试] 认证出错: ${error.message}`);

      if (error.response) {
        console.log(`[调试] HTTP状态码: ${error.response.status}`);
        console.log(`[调试] 错误响应:`, error.response.data);

        // 根据具体错误代码提供更详细的错误信息
        const errorCode = error.response.data?.code;
        const errorMsg = error.response.data?.msg;

        if (errorCode === 10013) {
          throw new Error(`App Key无效: ${errorMsg}`);
        } else if (errorCode === 10014) {
          throw new Error(`App Secret无效: ${errorMsg}`);
        } else {
          throw new Error(
            `飞书API认证失败 (${errorCode}): ${
              errorMsg || error.response.statusText
            }`
          );
        }
      }
      throw new Error(`网络请求失败: ${error.message}`);
    }
  }

  // 检查认证状态
  checkAuthStatus() {
    console.log(`[调试] 检查认证状态:`);
    console.log(`[调试] - App Key: ${this.appKey ? "已设置" : "未设置"}`);
    console.log(`[调试] - App Secret: ${this.appSecret ? "已设置" : "未设置"}`);
    console.log(
      `[调试] - Access Token: ${
        this.accessToken
          ? "已设置 (" + this.accessToken.substring(0, 20) + "...)"
          : "未设置"
      }`
    );

    if (!this.accessToken) {
      console.log(`[调试] ❌ 认证状态无效，需要重新认证`);
      return false;
    }

    console.log(`[调试] ✅ 认证状态有效`);
    return true;
  }

  async getSheets(spreadsheetToken) {
    console.log(`[调试] === 开始获取工作表列表 ===`);

    // 检查认证状态
    if (!this.checkAuthStatus()) {
      throw new Error("请先进行认证，当前没有有效的访问令牌");
    }

    // 验证spreadsheetToken格式
    if (!spreadsheetToken || spreadsheetToken.trim() === "") {
      throw new Error("表格ID不能为空");
    }

    const trimmedToken = spreadsheetToken.trim();
    console.log(`[调试] 正在访问表格ID: ${trimmedToken}`);

    try {
      const url = `${this.baseURL}/sheets/v3/spreadsheets/${trimmedToken}/sheets/query`;
      console.log(`[调试] 请求URL: ${url}`);
      console.log(
        `[调试] 使用的Access Token: ${this.accessToken.substring(0, 20)}...`
      );

      const headers = {
        Authorization: `Bearer ${this.accessToken}`,
        "Content-Type": "application/json; charset=utf-8",
      };
      console.log(`[调试] 请求头:`, {
        Authorization: `Bearer ${this.accessToken.substring(0, 20)}...`,
        "Content-Type": headers["Content-Type"],
      });

      const response = await axios.get(url, { headers });

      console.log(`[调试] API响应状态: ${response.status}`);
      console.log(`[调试] API响应代码: ${response.data.code}`);

      if (response.data.code !== 0) {
        console.log(`[调试] API返回错误:`, response.data);
        throw new Error(`获取工作表列表失败: ${response.data.msg}`);
      }

      console.log(
        `[调试] 成功获取 ${response.data.data?.sheets?.length || 0} 个工作表`
      );
      return response.data.data.sheets;
    } catch (error) {
      console.log(`[调试] 错误详情: ${error.message}`);
      if (error.response) {
        console.log(`[调试] HTTP状态码: ${error.response.status}`);
        console.log(`[调试] 响应数据:`, error.response.data);

        // 特别处理认证相关错误
        if (error.response.data?.code === 99991661) {
          throw new Error(
            `认证失败: 访问令牌缺失或无效。请检查App Key和App Secret是否正确。`
          );
        }

        if (error.response.status === 401) {
          throw new Error(`认证失败 (401): 访问令牌无效或已过期，请重新认证。`);
        }

        if (error.response.status === 403) {
          throw new Error(`权限不足 (403): 应用没有访问该表格的权限。`);
        }

        if (error.response.status === 404) {
          throw new Error(
            `表格未找到 (404): 请检查表格ID是否正确，或者应用是否有访问权限。表格ID: ${trimmedToken}`
          );
        }

        throw new Error(
          `获取工作表失败: ${
            error.response.data.msg || error.response.statusText
          }`
        );
      }
      throw new Error(`网络请求失败: ${error.message}`);
    }
  }

  async findSheetId(spreadsheetToken, sheetIdentifier) {
    const sheets = await this.getSheets(spreadsheetToken);

    // 先尝试按ID匹配
    let sheet = sheets.find((s) => s.sheet_id === sheetIdentifier);

    // 如果没找到，尝试按名称匹配
    if (!sheet) {
      sheet = sheets.find((s) => s.title === sheetIdentifier);
    }

    if (!sheet) {
      const availableSheets = sheets
        .map((s) => `${s.title} (${s.sheet_id})`)
        .join(", ");
      throw new Error(
        `未找到名为 "${sheetIdentifier}" 的工作表。可用的工作表: ${availableSheets}`
      );
    }

    return sheet.sheet_id;
  }

  async getSheetData(spreadsheetToken, sheetIdentifier, range = "") {
    if (!this.accessToken) {
      throw new Error("请先进行认证");
    }

    try {
      // 获取实际的sheet_id
      const sheetId = await this.findSheetId(spreadsheetToken, sheetIdentifier);

      // 使用v2 API（经验证可以工作）
      const url = `${this.baseURL}/sheets/v2/spreadsheets/${spreadsheetToken}/values/${sheetId}`;
      console.log(`[调试] === 使用v2 API获取工作表数据 ===`);
      console.log(`[调试] 表格Token: ${spreadsheetToken}`);
      console.log(`[调试] 工作表ID: ${sheetId}`);
      console.log(`[调试] 请求URL: ${url}`);

      const response = await axios.get(url, {
        headers: {
          Authorization: `Bearer ${this.accessToken}`,
          "Content-Type": "application/json; charset=utf-8",
        },
        params: {
          valueRenderOption: "FormattedValue",
          dateTimeRenderOption: "FormattedString",
        },
      });

      console.log(`[调试] v2 API响应状态: ${response.status}`);
      console.log(`[调试] v2 API响应代码: ${response.data.code}`);

      if (response.data.code === 0) {
        const values =
          response.data.data.valueRange?.values ||
          response.data.data?.values ||
          [];
        console.log(`[调试] v2 API成功获取 ${values.length} 行数据`);
        return values;
      } else {
        console.log(`[调试] v2 API返回错误:`, response.data);
        throw new Error(`v2 API错误: ${response.data.msg}`);
      }
    } catch (error) {
      console.log(`[调试] getSheetData错误: ${error.message}`);
      if (error.response) {
        console.log(`[调试] HTTP状态码: ${error.response.status}`);
        console.log(`[调试] 响应数据:`, error.response.data);
        throw new Error(
          `获取表格数据失败: ${
            error.response.data.msg || error.response.statusText
          }`
        );
      }
      throw new Error(`网络请求失败: ${error.message}`);
    }
  }

  async getSheetInfo(spreadsheetToken) {
    if (!this.accessToken) {
      throw new Error("请先进行认证");
    }

    try {
      const response = await axios.get(
        `${this.baseURL}/sheets/v3/spreadsheets/${spreadsheetToken}`,
        {
          headers: {
            Authorization: `Bearer ${this.accessToken}`,
            "Content-Type": "application/json; charset=utf-8",
          },
        }
      );

      if (response.data.code !== 0) {
        throw new Error(`获取表格信息失败: ${response.data.msg}`);
      }

      return response.data.data.spreadsheet;
    } catch (error) {
      if (error.response) {
        throw new Error(
          `获取表格信息失败: ${
            error.response.data.msg || error.response.statusText
          }`
        );
      }
      throw new Error(`网络请求失败: ${error.message}`);
    }
  }

  // 解析知识库URL，提取文档ID和工作表ID
  parseWikiUrl(wikiUrl) {
    try {
      const url = new URL(wikiUrl);

      // 从URL路径中提取文档ID
      const pathMatch = url.pathname.match(/\/wiki\/([a-zA-Z0-9]+)/);
      if (!pathMatch) {
        throw new Error("无法从URL中解析出文档ID");
      }
      const docToken = pathMatch[1];

      // 从查询参数中提取工作表ID
      const sheetId = url.searchParams.get("sheet");
      if (!sheetId) {
        throw new Error("URL中缺少sheet参数");
      }

      return {
        docToken,
        sheetId,
        domain: url.origin,
      };
    } catch (error) {
      throw new Error(`URL解析失败: ${error.message}`);
    }
  }

  // 检测URL类型
  detectUrlType(url) {
    if (url.includes("/wiki/")) {
      return "wiki";
    } else if (url.includes("/sheets/")) {
      return "sheets";
    } else {
      return "unknown";
    }
  }

  // 获取知识库中的表格数据
  async getWikiTableData(wikiUrl) {
    if (!this.accessToken) {
      throw new Error("请先进行认证");
    }

    const { docToken, sheetId } = this.parseWikiUrl(wikiUrl);
    console.log(`[调试] 知识库文档ID: ${docToken}`);
    console.log(`[调试] 工作表ID: ${sheetId}`);

    try {
      // 使用知识库API获取表格数据
      const url = `${this.baseURL}/wiki/v2/spaces/get_node`;
      console.log(`[调试] 请求URL: ${url}`);

      const response = await axios.post(
        url,
        {
          token: docToken,
          obj_type: "sheet",
        },
        {
          headers: {
            Authorization: `Bearer ${this.accessToken}`,
            "Content-Type": "application/json; charset=utf-8",
          },
        }
      );

      console.log(`[调试] API响应状态: ${response.status}`);
      console.log(`[调试] API响应代码: ${response.data.code}`);

      if (response.data.code !== 0) {
        // 如果知识库API不可用，尝试通过sheets API访问
        console.log(`[调试] 知识库API失败，尝试sheets API`);
        return await this.getSheetDataFromWiki(docToken, sheetId);
      }

      return response.data.data || [];
    } catch (error) {
      console.log(`[调试] 知识库API错误: ${error.message}`);
      // 回退到sheets API
      return await this.getSheetDataFromWiki(docToken, sheetId);
    }
  }

  // 通过sheets API访问知识库表格（回退方案）
  async getSheetDataFromWiki(docToken, sheetId) {
    try {
      console.log(`[调试] 尝试通过sheets API访问知识库表格`);

      // 尝试将文档Token作为spreadsheet token使用
      const response = await axios.get(
        `${this.baseURL}/sheets/v3/spreadsheets/${docToken}/values/${sheetId}`,
        {
          headers: {
            Authorization: `Bearer ${this.accessToken}`,
            "Content-Type": "application/json; charset=utf-8",
          },
          params: {
            valueRenderOption: "FormattedValue",
            dateTimeRenderOption: "FormattedString",
          },
        }
      );

      if (response.data.code !== 0) {
        throw new Error(`获取知识库表格数据失败: ${response.data.msg}`);
      }

      return response.data.data.valueRange.values || [];
    } catch (error) {
      console.log(`[调试] sheets API也失败: ${error.message}`);
      throw new Error(`无法访问知识库表格数据。请确保：
1. 应用有访问该文档的权限
2. 文档ID和工作表ID正确
3. 或者将数据复制到标准的飞书表格中`);
    }
  }
}

module.exports = new FeishuService();
